package cmich.cps.scheduler.gui;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;

import cmich.cps.scheduler.SchedulingSystem;
import cmich.cps.scheduler.data.Professor;

/**
 * The Class ProfessorController.
 * 
 * @author Jonathan Kissinger <kissi1j@cmich.edu>
 */
public class ProfessorController implements Controller {

	/** The table. */
	private final JTable table;

	/** The model. */
	private DefaultTableModel model;

	/** The system. */
	private SchedulingSystem system = SchedulingSystem.getInstance();

	private JComboBox<String> tbcComboBox = new JComboBox<String>();

	private int tbcColumn = 1;
	/**
	 * Instantiates a new professor controller.
	 *
	 * @param table the table
	 */
	@SuppressWarnings("serial")
	ProfessorController(JTable table) {
		this.table = table;
		String[] headers = { "Name", "Hours between courses", "Max courses", "Total preferences" };
		this.model = new DefaultTableModel(new Object[][] {}, headers ) {
			@Override  
			public Class<?> getColumnClass(int col) {
				if(col == 2) return Integer.class;
				else return String.class;
			}

			@Override
			public boolean isCellEditable(int rowIndex, int mColIndex) {
				if(mColIndex==3) return false;
				else return true;
			}
		};
		this.table.setModel(this.model);
		this.table.setAutoCreateRowSorter(true);
		this.table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		this.table.getTableHeader().setReorderingAllowed(false);
		//Sets room preference to use combo box.
		TableColumn tbcCol = table.getColumnModel().getColumn(tbcColumn);
		tbcCol.setCellEditor(new ComboBoxEditor());
	}

	/* (non-Javadoc)
	 * @see cmich.cps.scheduler.gui.Controller#populate()
	 */
	public void populate() {
		model.setRowCount(0);
		int totalMaxCourses = 0;
		for(Professor p : system.getProfessors()) {
			totalMaxCourses = totalMaxCourses + p.getMaxCourses();
			model.addRow(new Object[] { p.getName(), p.getTimeBetweenCourses(), p.getMaxCourses(), p.getPreferences().size() });
		}
		//Setup roomPreference comboBox
		tbcComboBox.removeAllItems();
		tbcComboBox.addItem("No preference");
		tbcComboBox.addItem("1 to 3");
		tbcComboBox.addItem("3 to 6");
		tbcComboBox.addItem("6 or more");
		table.setToolTipText(model.getRowCount() + " professors. " + totalMaxCourses + " total maximum courses.");
	}

	/* (non-Javadoc)
	 * @see cmich.cps.scheduler.gui.Controller#addFunctionality()
	 */
	public void addFunctionality() {
		model.addTableModelListener(new TableModelListener() {
			@Override
			public void tableChanged(TableModelEvent e) {
				switch (e.getType()) {
				case TableModelEvent.INSERT:
					//Unused
					break;
				case TableModelEvent.UPDATE:
					int row = e.getFirstRow();
					int col = e.getColumn();
					Object object = model.getValueAt(row, col);
					//Fix to handle clicking on the combo box, but then not selecting an option
					if(col==tbcColumn && object==null) {
						String aValue = system.getCourses().get(row).getRoomPreference();
						model.setValueAt(aValue, row, tbcColumn);
						break;
					}
					if(!system.modifyProfessor(row,  col, object)) {
						populate();
					}
					break;
				case TableModelEvent.DELETE:
					//Unused
					break;
				}
			}
		});
		table.addMouseListener(new TableMenu());
		table.getParent().addMouseListener(new TableMenu());
	}

	/**
	 * @author Jonathan Kissinger <kissi1j@cmich.edu>
	 * 
	 * The Class TableMenu.
	 */
	private class TableMenu extends MouseAdapter {

		/* (non-Javadoc)
		 * @see java.awt.event.MouseAdapter#mouseReleased(java.awt.event.MouseEvent)
		 */
		@Override
		public void mouseReleased(MouseEvent e) {
			if (e.isPopupTrigger()) {
				JPopupMenu popup = new JPopupMenu();
				JMenuItem addItem = new JMenuItem("Add new professor");
				addItem.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent e) {
						if(system.addProfessor()) {
							populate();
						}
					}
				});
				popup.add(addItem);
				int row = table.rowAtPoint(e.getPoint());
				if (row >= 0 && row < table.getRowCount()) {
					final int index = table.convertRowIndexToModel(row);
					Professor professor = system.getProfessors().get(index);
					JMenuItem deleteItem = new JMenuItem("Delete " + professor.getName());
					deleteItem.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							system.removeProfessor(index);
							model.removeRow(index);
						}
					});
					JMenuItem preferenceItem = new JMenuItem("Edit preferences for " + professor.getName());
					preferenceItem.addActionListener(new ActionListener() {
						@Override
						public void actionPerformed(ActionEvent e) {
							Frame.getInstance().editProfessorPreferences(system.getProfessors().get(index));
						}
					});
					popup.add(preferenceItem);
					popup.add(deleteItem);
					table.setRowSelectionInterval(row, row);
				} else {
					table.clearSelection();
				}
				popup.show(e.getComponent(), e.getX(), e.getY());
			}
			else if(e.getClickCount()==2 && table.columnAtPoint(e.getPoint())==3) {
				int row = table.rowAtPoint(e.getPoint());
				if (row >= 0 && row < table.getRowCount()) {
					final int index = table.convertRowIndexToModel(row);
					Frame.getInstance().editProfessorPreferences(system.getProfessors().get(index));
				}
			}
		}
	}
	
	/**
	 * @author Jonathan Kissinger <kissi1j@cmich.edu>
	 * 
	 * The Class ComboBoxEditor.
	 */
	private class ComboBoxEditor extends DefaultCellEditor {
		
		/** The Constant serialVersionUID. */
		private static final long serialVersionUID = 10L;
		
		/**
		 * Instantiates a new combo box editor.
		 */
		public ComboBoxEditor() {
			super(tbcComboBox);
		}
	}
}